今日目標
按下分享經驗後跳出表單,填寫完後按分享經驗按鈕就可以囉
在 src/components 中新增 NewPostModal.vue
<template>
  <div v-if="visible" class="modal-overlay" @click.self="close">
    <div class="modal-content share-modal">
      <div class="modal-header">
        <h3 class="modal-title">✍ 分享你的推甄經驗</h3>
        <button class="close-btn" @click="close">×</button>
      </div>
      
      <div class="modal-body">
        <form @submit.prevent="submitExperience" class="share-form">
          <div class="form-section">
            <h4 class="section-title">📚 基本資訊</h4>
            <div class="form-grid">
              <div class="form-group">
                <label class="form-label">學校</label>
                <input 
                  v-model="formData.pSchool" 
                  type="text" 
                  class="form-input" 
                  placeholder="例:台灣大學"
                  required
                />
              </div>
              <div class="form-group">
                <label class="form-label">系所</label>
                <input 
                  v-model="formData.pDep" 
                  type="text" 
                  class="form-input" 
                  placeholder="例:資訊管理學系"
                  required
                />
              </div>
              <div class="form-group">
                <label class="form-label">推甄年度</label>
                <input 
                  v-model="formData.pYear" 
                  type="text" 
                  class="form-input" 
                  placeholder="例:114"
                  required
                />
              </div>
              <div class="form-group">
                <label class="form-label">成績排名</label>
                <input 
                  v-model="formData.pScore" 
                  type="text" 
                  class="form-input" 
                  placeholder="例:5% 或 系排第3"
                />
              </div>
              <div class="form-group">
                <label class="form-label">GPA (選填)</label>
                <input 
                  v-model="formData.pGPA" 
                  type="text" 
                  class="form-input" 
                  placeholder="例:4.0/4.0"
                />
              </div>
            </div>
          </div>
          <div class="form-section">
            <h4 class="section-title">🌟 經歷與背景</h4>
            <div class="form-group">
              <label class="form-label">詳細經歷</label>
              <textarea 
                v-model="formData.pExp" 
                class="form-textarea" 
                rows="6"
                placeholder="請分享你的經歷,例如:
- 專題研究
- 實習經驗
- 競賽得獎
- 證照考取
- 社團活動
- 其他特殊經歷"
                required
              ></textarea>
            </div>
          </div>
          <div class="form-section">
            <h4 class="section-title">🎯 推甄結果</h4>
            <div class="form-group">
              <label class="form-label">申請結果</label>
              <textarea 
                v-model="formData.pResult1" 
                class="form-textarea" 
                rows="6"
                placeholder="請分享你的申請結果,例如:
台大資管 一階落榜
政大資管 正取
成大資管 備取5
中央資管 正取"
                required
              ></textarea>
            </div>
          </div>
          <div class="form-section">
            <h4 class="section-title">🔗 來源連結 (選填)</h4>
            <div class="form-group">
              <label class="form-label">原文連結</label>
              <input 
                v-model="formData.pURL" 
                type="url" 
                class="form-input" 
                placeholder="例:https://www.dcard.tw/f/graduate_school/p/..."
              />
            </div>
          </div>
          <div class="form-actions">
            <button type="button" class="btn btn-secondary" @click="close">
              取消
            </button>
            <button type="submit" class="btn btn-primary" :disabled="isSubmitting">
              {{ isSubmitting ? '分享中...' : '✨ 分享經驗' }}
            </button>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive } from 'vue'
const props = defineProps({
  visible: { type: Boolean, default: false }
})
const emit = defineEmits(['close', 'submit'])
const isSubmitting = ref(false)
const formData = reactive({
  pSchool: '',
  pDep: '',
  pYear: '',
  pScore: '',
  pGPA: '',
  pExp: '',
  pResult1: '',
  pURL: ''
})
function close() {
  emit('close')
  resetForm()
}
function resetForm() {
  Object.keys(formData).forEach(key => {
    formData[key] = ''
  })
}
async function submitExperience() {
  if (isSubmitting.value) return
  
  isSubmitting.value = true
  
  try {
    const newExperience = {
      pId: `p_${Date.now()}`,
      pDate: new Date().toLocaleDateString('zh-TW', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit'
      }).replace(/\//g, '/'),
      pDcardId: null,
      pURL: formData.pURL || null,
      pYear: formData.pYear,
      pContent: `背景:
學校/系所:${formData.pSchool} ${formData.pDep}
${formData.pScore ? `成績排名:${formData.pScore}` : ''}
${formData.pGPA ? `GPA:${formData.pGPA}` : ''}
經歷:
${formData.pExp}
結果:
${formData.pResult1}`,
      pSchool: formData.pSchool,
      pDep: formData.pDep,
      p_sd_sId: "user_submitted",
      p_sd_dId: "user_submitted",
      pScore: formData.pScore || null,
      pGPA: formData.pGPA || null,
      pExp: formData.pExp,
      pResult1: formData.pResult1
    }
    
    emit('submit', newExperience)
    
    alert('感謝你的分享!你的經驗已成功加入資料庫 ✨')
    
    close()
  } catch (error) {
    console.error('提交失敗:', error)
    alert('提交失敗,請稍後再試')
  } finally {
    isSubmitting.value = false
  }
}
</script>
<script setup>
import NewPostModal from './components/NewPostModal.vue'
...
const showShareModal = ref(false)
const allPosts = ref([...posts])
function openShareModal() {
  showShareModal.value = true
}
function handleNewExperience(newExperience) {
  allPosts.value.unshift(newExperience)
  showShareModal.value = false
  keyword.value = ''
  currentPage.value = 1
}
...
</script>
<template>
  <Header @share="openShareModal" />
  <main>
      ...
    <NewPostModal :visible="showShareModal" @close="showShareModal=false" @submit="handleNewExperience" />
  </main>
</template>
<template>
  <header class="header">
    <div class="header-content">
      <h1 class="logo">
        ✦ 推甄經驗分享 ✦
      </h1>
      <button class="add-btn" @click="handleShare">
        ✍ 分享經驗
      </button>
    </div>
  </header>
</template>
<script setup>
  const emit = defineEmits(['share'])
  function handleShare() {
    emit('share')
  }
</script>
但是目前還沒接到資料的 API,所以資料只會暫時新增上去
ref
import { ref } from 'vue'
const count = ref(0)     
console.log(count.value) // 讀寫要用 .value
count.value++
<template>
  <button @click="count++"> {{ count }} </button> <!-- 在模板可直接用 -->
</template>
reactive
import { reactive } from 'vue'
const form = reactive({
  school: '',
  dep: '',
  year: ''
})
form.school = '台大' // 直接改屬性
<template>
  <input v-model="form.school" placeholder="學校"/>
  <p>輸入的學校是:{{ form.school }}</p>
</template>
小結
- 實作新增資料功能
- ref 與 reaactive 差異